
function defineValueStateGet() {

    if (bindingTarget)
    {
        subscribeBinding(this, 'value');
    }

    return this.__value;
}


function defineValueStateSet(value) {

    if (value !== this.__value)
    {
        var dependences = this.__deps;

        // 更新值
        this.__value = value;

        // 触发订阅通知
        if (dependences && dependences.value)
        {
            notifyDependences(dependences, 'value');
        }
    }
}


// 简单数值状态类
function ValueState(value) {

    this.__value = value;
    this.__deps = null;
    this.__model = 4; // 模型类型

    $define(this, 'value', {
        get: this.toString = this.valueOf = defineValueStateGet,
        set: defineValueStateSet
    });
}




// 定义对象状态
function defineObjectState(object) {

    var define = defineObjectStateProperty;
    var fields = {};

    var state = {
        __fields: fields,
        __subs: null,
        __deps: null,
        __model: 3, // 模型类型
        __destroy: stateDestroy
    };

    var subs;

    for (var name in object)
    {
        var value = object[name];

        if (!value || typeof value !== 'object' || !value.__model)
        {
            fields[name] = value;
            define(state, name, propertyConvertors[typeof value]);
        }
        else // DataModel || ObjectModel || state || ValueState
        {
            switch (value.__model)
            {
                case 1:
                    defineSubArrayState(state, name, value);
                    break;
            
                case 2:
                case 3:
                    defineSubObjectState(state, name, value);
                    break;

                case 4:
                    defineSubValueState(state, name, value);
                    break;
            }

            if (subs = state.__subs)
            {
                subs.push(value);
            }
            else
            {
                state.__subs = [value];
            }
        }
    }

    return state;
}


// 定义对象状态属性
function defineObjectStateProperty(provider, name, convert) {

    var notify = notifyDependences;

    $define(provider, name, {

        get: function () {

            if (bindingTarget)
            {
                subscribeBinding(this, name);
            }

            return this.__fields[name];
        },
        set: function (value) {

            var fields = this.__fields;
            var dependences;

            if (convert)
            {
                value = convert(value);
            }

            if (value !== fields[name])
            {
                // 更新值
                fields[name] = value;

                // 触发订阅通知
                if ((dependences = this.__deps) && (dependences[name] || dependences['*']))
                {
                    notify(dependences, name);
                }
            }
        }
    });
}


// 定义子数组状态
function defineSubArrayState(provider, name, state) {

    $define(provider, name, {

        get: function () {

            return state;
        },

        set: function (value) {

            if (value && value.length > 0)
            {
                state.load(value);
            }
            else
            {
                state.clear();
            }
        }
    });
}


// 定义子对象状态
function defineSubObjectState(provider, name, state) {

    $define(provider, name, {

        get: function () {

            return state;
        },

        set: function (value) {

            for (var key in value)
            {
                state[key] = value[key];
            }
        }
    });
}


// 定义子值状态
function defineSubValueState(provider, name, state) {

    $define(provider, name, {

        get: function () {

            return state.value;
        },

        set: function (value) {

            state.value = value;
        }
    });
}


// 销毁状态
function stateDestroy() {

    var subs = this.__subs;
    var state;

    for (var i = subs.length; i--;)
    {
        if ((state = subs[i]) && state.__destroy)
        {
            state.__destroy();
        }
    }

    this.__subs = null;
    removeDependences(this);
}

